﻿using System;
[assembly: CLSCompliant(false)]
namespace Microsoft.ExternalResearch.CreativeCommons.PowerPoint
{
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Office.Tools.Ribbon;
    using System.Drawing;
    using PowerPoint = Microsoft.Office.Interop.PowerPoint;
    using Microsoft.ExternalResearch.CreativeCommons.Common;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.InteropServices;
    using Microsoft.Office.Interop.PowerPoint;
    using Microsoft.Office.Core;
    using System.Xml;
    using System.Globalization;

    /// <summary>
    /// Represents the ribbon for Creative Commons Add-in for Microsoft PowerPoint.
    /// </summary>
    public partial class CreativeCommonsRibbonTab : OfficeRibbon
    {
        /// <summary>
        /// Image of the license.
        /// </summary>
        private Image license;

        /// <summary>
        /// Creates an instance of this class.
        /// </summary>
        public CreativeCommonsRibbonTab()
        {
            this.InitializeComponent();
            ThisAddIn.ApplicationStartedEvent += new EventHandler(this.ThisAddInApplicationStarted);
        }



        /// <summary>
        /// Sets a value indicating whether the presentation is licensed.
        /// </summary>
        private bool PresentationLicensed
        {
            get
            {
                return this.licensedGallery.Visible;
            }
            set
            {
                this.licensedGallery.Visible = value;
                this.notLicensedButton.Visible = !value;
            }
        }

        /// <summary>
        /// Sets a value indicating whether ribbon UI is enabled.
        /// </summary>
        private bool RibbonEnabled
        {
            get
            {
                return this.licensesRibbonGallery.Enabled;
            }
            set
            {
                this.licensedGallery.Enabled = value;
                this.notLicensedButton.Enabled = value;
                this.licensesRibbonGallery.Enabled = value;
            }
        }

        /// <summary>
        /// Sets the license image in ribbon UI.
        /// </summary>
        private Image LicenseImage
        {
            get
            {
                return this.license;
            }
            set
            {
                LicenseInfo licenseInfo = Helper.ReadLicenseInfo((DocumentProperties)ThisAddIn.PowerPointApplication.ActivePresentation.CustomDocumentProperties);
                this.licensedGallery.Items[0].Label = Helper.GetLicenseLabel(licenseInfo.Id);
                this.licensedGallery.Items[0].Image = value;

                this.license = value;
            }
        }

        /// <summary>
        /// Prepares the cache folders.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void CreativeCommonsRibbonTabLoad(object sender, RibbonUIEventArgs e)
        {
            Helper.PrepareLicenseFolders();

            // Set localized labels
            this.tabAttributes.Label = Helper.GetString("CreativeCommons");
            this.groupCreativeCommons.Label = Helper.GetString("CreativeCommons");
            this.licensedGallery.Label = Helper.GetString("Licensed", new object[] { "Presentation" });
            this.notLicensedButton.Label = Helper.GetString("NotLicensed", new object[] { "Presentation" });
            this.licensesRibbonGallery.Label = Helper.GetString("Licenses");
            this.removeLicenseButton.Label = Helper.GetString("RemoveLicenseFromDocument", new object[] { "Presentation" });
            this.newLicenseButton.Label = Helper.GetString("NewLicense");
            this.removeLicensesButton.Label = Helper.GetString("RemoveLicensesFromDisk");
            this.notLicensedButton.SuperTip = Helper.GetString("LicenseIndicatorToolTip");
            this.licensedGallery.SuperTip = Helper.GetString("LicenseGalleryToolTip");
            this.licensesRibbonGallery.SuperTip = Helper.GetString("LicensesGalleryToolTip");

            this.newLicenseButton.Click += this.NewLicense;
            this.removeLicenseButton.Click += new EventHandler<RibbonControlEventArgs>(this.RemoveLicenseFromDocumentButtonClick);
            this.removeLicensesButton.Click += new EventHandler<RibbonControlEventArgs>(this.RemoveLicensesButtonClick);
            this.licensedGallery.ItemsLoading += new EventHandler<RibbonControlEventArgs>(this.LicensedGalleryItemsLoading);
        }

        /// <summary>
        /// Updates the ribbon UI.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void LicensedGalleryItemsLoading(object sender, RibbonControlEventArgs e)
        {
            this.UpdateRibbonUI();
        }

        /// <summary>
        /// Associates the event handlers when application starts.
        /// </summary>
        private void ThisAddInApplicationStarted(System.Object sender, System.EventArgs e)
        {
            ThisAddIn.PowerPointApplication.WindowActivate += new EApplication_WindowActivateEventHandler(this.PowerPointApplicationWindowActivate);
            ThisAddIn.PowerPointApplication.PresentationOpen += new EApplication_PresentationOpenEventHandler(this.PowerPointApplicationPresentationOpen);

            // This call is required to handle the scenario when the add-in is disabled via Options and enabled again.
            this.UpdateRibbonUI();
        }

        /// <summary>
        /// Updates the ribbon UI when a presentation is opened.
        /// </summary>
        /// <param name="pres">Presentation object.</param>
        private void PowerPointApplicationPresentationOpen(Presentation pres)
        {
            this.UpdateRibbonUI();
        }

        /// <summary>
        /// Updates the ribbon UI when user switches between presentations.
        /// </summary>
        /// <param name="pres">Presentation object.</param>
        /// <param name="wn">PowerPoint window.</param>
        private void PowerPointApplicationWindowActivate(Presentation pres, DocumentWindow wn)
        {
            this.UpdateRibbonUI();
        }

        /// <summary>
        /// Invokes the "Remove licenses from disk" dialog.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void RemoveLicensesButtonClick(object sender, RibbonControlEventArgs e)
        {
            RemoveLicensesDialog dlg = new RemoveLicensesDialog();
            dlg.ShowDialog();
        }

        /// <summary>
        /// Removes the Creative Commons license from the workbook.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void RemoveLicenseFromDocumentButtonClick(object sender, RibbonControlEventArgs e)
        {
            if (null != Helper.ReadLicenseInfo((DocumentProperties)ThisAddIn.PowerPointApplication.ActivePresentation.CustomDocumentProperties))
            {
                if (!Helper.GetUserResponse(Helper.GetString("RemoveLicenseMessage", new object[] { "presentation" })))
                {
                    return;
                }
            }

            ThisAddIn.RemoveLicenseFromDocument();
            ThisAddIn.PowerPointApplication.ActivePresentation.Saved = MsoTriState.msoFalse;
            this.UpdateRibbonUI();
        }


        /// <summary>
        /// Loads and displays the available licenses in the ribbon UI.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void LoadLicenses(object sender, RibbonControlEventArgs e)
        {

            this.UpdateRibbonUI();
            this.licensesRibbonGallery.Items.Clear();

            if (Directory.Exists(Helper.LocalLicensesFolderPath))
            {
                foreach (string dir in Directory.GetDirectories(Helper.LocalLicensesFolderPath))
                {
                    RibbonDropDownItem item = new RibbonDropDownItem();
                    item.Tag = dir.Substring(Helper.LocalLicensesFolderPath.Length + @"\".Length);

                    if (FileAttributes.Hidden != (File.GetAttributes(dir) & FileAttributes.Hidden))
                    {
                        continue;
                    }

                    if (!File.Exists(Path.Combine(dir, Helper.LicenseFileName)) || !File.Exists(Path.Combine(dir, Helper.LicenseImageFileName)))
                    {
                        continue;
                    }

                    try
                    {
                        item.Image = Helper.GetImageFromFile(Path.Combine(dir, Helper.LicenseImageFileName));
                    }
                    catch (FileNotFoundException)
                    {
                        // Ignore if the icon file is missing.
                    }

                    this.licensesRibbonGallery.Items.Add(item);
                    this.licensesRibbonGallery.Items[this.licensesRibbonGallery.Items.Count - 1].Label = Helper.GetLicenseLabel(item.Tag.ToString());
                }
            }

            // Disable 'Remove Licenses' button if there is no license is available for removal.
            this.removeLicensesButton.Visible = !(0 == this.licensesRibbonGallery.Items.Count);
        }

        /// <summary>
        /// Invokes the "New license" wizard.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void NewLicense(object sender, RibbonControlEventArgs e)
        {
            NewLicenseWizard newLicenseWizard = new NewLicenseWizard();
            newLicenseWizard.ShowDialog();
        }

        /// <summary>
        /// Associates the selected Creative Commons license with the workbook.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void AssociateLicense(object sender, RibbonControlEventArgs e)
        {

            if (null != Helper.ReadLicenseInfo((DocumentProperties)ThisAddIn.PowerPointApplication.ActivePresentation.CustomDocumentProperties))
            {
                if (!Helper.GetUserResponse(Helper.GetString("ReAssociateConfirmMessage", new object[] { "presentation" })))
                {
                    return;
                }
            }

            ThisAddIn.RemoveLicenseFromDocument();
            string licname = this.licensesRibbonGallery.Items[this.licensesRibbonGallery.SelectedItemIndex].Tag.ToString();
            string[] licenseLogoInfo = Helper.GetLicenseInfo(licname);
            licenseLogoInfo[0] = RemoveJunkCharactersFromLicenseText(licenseLogoInfo[0]);
            string imgFilePath = Path.Combine(Path.Combine(Helper.LocalLicensesFolderPath, licname), Helper.LicenseImageFileName);

            Image img = this.licensesRibbonGallery.Items[this.licensesRibbonGallery.SelectedItemIndex].Image;

            PpViewType originalView = ThisAddIn.PowerPointApplication.ActiveWindow.ViewType;
            ThisAddIn.PowerPointApplication.ActiveWindow.ViewType = PpViewType.ppViewSlide;

            float left = 1, top = 1;

            if (null != img)
            {
                ThisAddIn.PowerPointApplication.ActiveWindow.Selection.SlideRange.Shapes.AddPicture(imgFilePath,
                    Microsoft.Office.Core.MsoTriState.msoFalse,
                    Microsoft.Office.Core.MsoTriState.msoCTrue,
                    Convert.ToSingle(left, CultureInfo.CurrentCulture),
                    Convert.ToSingle(top, CultureInfo.CurrentCulture),
                    Convert.ToSingle(img.Width * Helper.PixelPointRatio, CultureInfo.CurrentCulture),
                    Convert.ToSingle(img.Height * Helper.PixelPointRatio, CultureInfo.CurrentCulture)).Select(MsoTriState.msoCTrue);

                ThisAddIn.PowerPointApplication.ActiveWindow.Selection.ShapeRange.Left = 1;
                left = ThisAddIn.PowerPointApplication.ActiveWindow.Selection.ShapeRange.Left;
                top = ThisAddIn.PowerPointApplication.ActiveWindow.Selection.ShapeRange.Top
                    + ThisAddIn.PowerPointApplication.ActiveWindow.Selection.ShapeRange.Height + 5;
            }

            float width = ThisAddIn.PowerPointApplication.ActiveWindow.Selection.SlideRange.Master.Width;
            ThisAddIn.PowerPointApplication.ActiveWindow.Selection.SlideRange.Shapes.AddTextbox(MsoTextOrientation.msoTextOrientationHorizontal, left, top, width, 200).Select(MsoTriState.msoFalse);
            ThisAddIn.PowerPointApplication.ActiveWindow.Selection.TextRange.Text = licenseLogoInfo[2];
            TextRange textRange = ThisAddIn.PowerPointApplication.ActiveWindow.Selection.TextRange.InsertAfter(licenseLogoInfo[0]);
            textRange.Select();
            textRange.ActionSettings[PpMouseActivation.ppMouseClick].Hyperlink.Address = licenseLogoInfo[1];
            if (false == string.IsNullOrEmpty(licenseLogoInfo[3]))
            {
                ThisAddIn.PowerPointApplication.ActiveWindow.Selection.TextRange.InsertAfter(licenseLogoInfo[3]);
            }
            ThisAddIn.PowerPointApplication.ActiveWindow.ViewType = originalView;
            DocumentProperties customProperties = (DocumentProperties)ThisAddIn.PowerPointApplication.ActivePresentation.CustomDocumentProperties;
            LicenseInfo licenseInfo = new LicenseInfo();
            licenseInfo.Id = this.licensesRibbonGallery.Items[this.licensesRibbonGallery.SelectedItemIndex].Tag.ToString();
            licenseInfo.LicenseUrl = licenseLogoInfo[1];
            licenseInfo.LicenseXml = licenseLogoInfo[4];

            // Save the license information in presenttaion.
            Helper.SaveLicenseInfo((DocumentProperties)ThisAddIn.PowerPointApplication.ActivePresentation.CustomDocumentProperties, licenseInfo);
            ThisAddIn.PowerPointApplication.ActivePresentation.Saved = MsoTriState.msoFalse;
            this.license = img;

            this.UpdateRibbonUI();
        }



        /// <summary>
        /// Updates the ribbon UI based on the state of PowerPoint and presentation.
        /// </summary>
        private void UpdateRibbonUI()
        {
            if (null != ThisAddIn.PowerPointApplication)
            {
                // When PowerPoint is opened without a presentation.
                if (!ThisAddIn.HasPresentation())
                {
                    this.PresentationLicensed = false;
                    this.RibbonEnabled = false;
                }

                // When the presenttaion does not have a license.
                else if (null == Helper.ReadLicenseInfo((DocumentProperties)ThisAddIn.PowerPointApplication.ActivePresentation.CustomDocumentProperties))
                {
                    this.PresentationLicensed = false;
                    this.RibbonEnabled = true;
                }

                // When the presentation has a license.
                else
                {
                    LicenseInfo licenseInfo = Helper.ReadLicenseInfo((DocumentProperties)ThisAddIn.PowerPointApplication.ActivePresentation.CustomDocumentProperties);
                    this.RibbonEnabled = true;
                    this.PresentationLicensed = true;
                    this.LicenseImage = licenseInfo.Image;
                }
            }
        }

        /// <summary>
        /// Removes redundant characters like \r & \n from the string, also removes some extra spaces
        /// </summary>
        /// <param name="str">string from which to remove the junk characters</param>
        /// <returns>Modified string</returns>
        private string RemoveJunkCharactersFromLicenseText(string str)
        {
            try
            {
                StringBuilder strBuilder = new StringBuilder(str);
                strBuilder = strBuilder.Replace("\r\n ", "");
                strBuilder = strBuilder.Replace("\r\n", "");
                str = strBuilder.ToString();
            }
            catch (Exception)
            {
            }
            return str;
        }
    }
}
